/*
 *  $Id: HandCard.cs 1235 2011-03-23 11:06:29Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using Nereal.Extensions;
using Nereal.Serialization;

namespace Ragima {
    /// <summary>
    /// Тип цели: карта в руках.
    /// </summary>
    public class HandCardTarget : TargetType {
        /// <summary>
        /// Цель: любая карта в руках.
        /// </summary>
        public static readonly HandCardTarget Any = new HandCardTarget(new Languages.Phrase("target.handcard.any"));
        /// <summary>
        /// Цель: открытая карта в руках.
        /// </summary>
        public static readonly HandCardTarget Opened = new HandCardTarget(new Languages.Phrase("target.handcard.opened"), IsOpened);
        /// <summary>
        /// Цель: закрытая карта в руках.
        /// </summary>
        public static readonly HandCardTarget Closed = new HandCardTarget(new Languages.Phrase("target.handcard.closed"), IsClosed);

        private TargetPredicate<HandCard> _condition;

        public HandCardTarget(Languages.Phrase notice) : this(notice, null) {
        }
        public HandCardTarget(Languages.Phrase notice, TargetPredicate<HandCard> condition) : base(notice) {
            _condition = condition;
        }

        public override bool IsRealTarget {
            get { return true; }
        }

        protected override void AutoSelectTab(Player player) {
            player.DefaultTab = TabType.Cards;
            player.SelectPlayer(player);
        }

        /// <summary>
        /// Число целей равно числу карт в руках.
        /// </summary>
        public override int GetCount(AbstractObject caster) {
            return caster.Owner.Hands.Count;
        }

        /// <summary>
        /// Целевые регионы: карты в руках.
        /// </summary>
        public override bool AcceptRegion(Region region) {
            var phr = region as PlayerHandCardRegion;
            if (phr == null)
                return false;
            if (_condition != null && !_condition(Request, phr.Card))
                return false;
            return true;
        }

        public override TargetArgs GetArgs(Region region) {
            var phr = region as PlayerHandCardRegion;
            return phr != null ? new HandCardTargetArgs(Request.Player, Request.Caster, phr.Card) : null;
        }

        /// <summary>
        /// Условие на карту в руках: открытая.
        /// </summary>
        public static bool IsOpened(TargetRequest request, HandCard card) {
            return card.Opened;
        }
        /// <summary>
        /// Условие на карту в руках: закрытая.
        /// </summary>
        public static bool IsClosed(TargetRequest request, HandCard card) {
            return !card.Opened;
        }
    }

    [TypeId("handcard")]
    public class HandCardTargetArgs : TargetArgs<HandCardData> {
        [Serialize, XmlName("target")]
        private HandCardData _target;

        public HandCardTargetArgs() {
        }
        public HandCardTargetArgs(Player player, AbstractObject caster, HandCard target) : base(player, caster) {
            _target = new HandCardData(player, target);
        }

        public override HandCardData Target {
            get { return _target; }
        }
    }

    public struct HandCardData {
        [XmlName("owner"), Reference(true, typeof(bool), Serialization.Resolvers.GamePlayer)]
        public Player Owner;

        [XmlName("card"), DefaultValue(-1)]
        public int CardIndex;

        public HandCardData(Player owner, HandCard card) {
            Owner = owner;
            CardIndex = owner != null ? owner.Hands.IndexOf(card) : -1;
        }

        [NotSerialize]
        public HandCard Card {
            get { return Owner != null ? Owner.Hands.GetOrDefault(CardIndex, null) : null; }
        }

        public static implicit operator HandCard(HandCardData data) {
            return data.Card;
        }
    }
}
